﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StudentManagerApplication.Model;

namespace StudentManagerApplication
{
    class StudentManager : Singleton<StudentManager>
    {
        public void Start()
        {
            init();
            PageOne();
            Console.ReadKey();
        }

        private void PageOne()
        {
            PrintMenu("欢迎进入学生管理系统");
            Console.Write("请输入管理员帐号：");
            string account = Console.ReadLine();
            Console.Write("请输入管理员密码：");
            string pass = Console.ReadLine();
            if (!pass.Equals("root") || !account.Equals("root"))
            {
                Console.WriteLine();
                Console.WriteLine("帐号或密码错误，请重新输入");
                Console.WriteLine();
                PageOne();
            }
            else
            {
                Console.Clear();
                PageTwo();
            }
        }

        private void PageTwo()
        {
            PrintModuleWithOutExit("欢迎root管理员", "1：信息数据管理模块", "2：基本信息管理模块", "3：成绩管理模块", "4：退出系统");
            string s = Console.ReadLine();
            switch (s)
            {
                case "1":
                    Console.Clear();
                    MessageDataManagerPage();
                    break;
                case "2":
                    Console.Clear();
                    BasicMessageManagerPage();
                    break;
                case "3":
                    Console.Clear();
                    ScoreManagerPage();
                    break;
                case "4":
                    Environment.Exit(0);
                    break;
                default:
                    Console.Clear();
                    PrintBetweenEmptyLine("输入有误，请重新输入");
                    PageTwo();
                    break;
            }
        }

        /// <summary>
        /// 1.学生基本信息录入
        /// 2.所选科目成绩录入
        /// 3.所选科目成绩导出
        /// </summary>
        private void MessageDataManagerPage()
        {
            LastPage = PageTwo;
            PrintModule("欢迎进入信息数据管理模块", "1.学生基本信息录入", "2.所选科目成绩录入", "3.所选科目成绩导出");
            string s = Console.ReadLine();
            switch (s)
            {
                case "1":
                    Console.Clear();
                    StudentMessageSavePage();
                    break;
                case "2":
                    Console.Clear();
                    SubjectScoreSavePage();
                    break;
                case "3":
                    Console.Clear();
                    SubjectScoreSelectPage();
                    break;
                case "4":
                    Console.Clear();
                    LastPage();
                    break;
                case "5":
                    Environment.Exit(0);
                    break;
                default:
                    Console.Clear();
                    PrintBetweenEmptyLine("输入有误，请重新输入");
                    MessageDataManagerPage();
                    break;
            }
        }

        /// <summary>
        /// 学生基本信息录入
        /// </summary>
        private void StudentMessageSavePage()
        {
            LastPage = MessageDataManagerPage;
            Console.Write("请输入学生名字：");
            string studentname = Console.ReadLine();
            int age = 0;
            PrintAndReadInt("请输入学生年龄：", int.MaxValue, out age);

            foreach (Profession progession in professions)
            {
                Console.WriteLine("{0}:{1}", progession.Id, progession.ProfessionName);
            }

            int professionID = 0;
            PrintAndReadInt("请输入专业编号：", professions.Count, out professionID);

            foreach (Grade grade in professions[professionID].Grades)
            {
                Console.WriteLine("{0}:{1}", grade.Id, grade.Gradename);
            }

            int gradeID = 0;
            PrintAndReadInt("请输入年级编号：", professions[professionID].Grades.Count,out gradeID);

            Student student = new Student(studentname, age);
            student.Grade = professions[professionID].Grades[gradeID];
            professions[professionID].Grades[gradeID].Students.Add(student);
            students.Add(student);

            Console.Clear();

            PrintBeforeEmptyLine("保存成功");
            while (true)
            {
                PrintModuleWithOutTitle("1:输入该学生的科目成绩");
                string s1 = Console.ReadLine();
                if (s1.Equals("1"))
                {
                    foreach (Subject subject in subjects)
                    {
                        Console.WriteLine("{0}:{1}",subject.Id,subject.SubjectName);
                    }
                    int subjectID = 0;
                    PrintAndReadInt("请输入科目编号：",subjects.Count,out subjectID);

                    int subjectScore = 0;
                    PrintAndReadInt("请输入科目成绩：", int.MaxValue, out subjectScore);

                    Subject su = subjects[subjectID];
                    Subject sub = new Subject(su.Id, su.SubjectName, subjectScore);

                    professions[professionID].Grades[gradeID].Subjects[subjectID].Students.Add(student);
                    //professions[professionID].Grades[gradeID].Students.Add(student);
                    student.Subjects.Add(sub);

                    Console.Clear();

                    PrintBeforeEmptyLine("保存成功");

                    continue;
                }
                else if (s1.Equals("2"))
                {
                    Console.Clear();
                    LastPage();
                    break;
                }
                else if (s1.Equals("3"))
                {
                    Environment.Exit(0);
                    break;
                }
            }
        }

        /// <summary>
        /// 所选科目成绩录入
        /// </summary>
        private void SubjectScoreSavePage()
        {
            LastPage = MessageDataManagerPage;
            foreach (Student student in students)
            {
                Console.WriteLine("{0}:{1}", student.Id, student.StudentName);
            }
            int studentID = 0;
            PrintAndReadInt("请输入学生编号：", students.Count, out studentID);

            foreach (Subject subject in subjects)
            {
                Console.WriteLine("{0}:{1}", subject.Id, subject.SubjectName);
            }
            int subjectID = 0;
            PrintAndReadInt("请输入科目编号：", subjects.Count, out subjectID);

            int subjectScore = 0;
            PrintAndReadInt("请输入科目成绩：", 0, out subjectScore);

            Subject su = subjects[subjectID];
            Subject sub = new Subject(su.Id, su.SubjectName, subjectScore);

            if (students[studentID].Subjects.Contains(sub))
            {
                students[studentID].Subjects[subjectID].Score = sub.Score;
            }
            else
            {
                students[studentID].Subjects.Add(sub);
            }

            Console.Clear();

            PrintBeforeEmptyLine("保存成功");

            LastPage();
            
        }

        /// <summary>
        /// 所选科目成绩导出
        /// </summary>
        private void SubjectScoreSelectPage()
        {
            LastPage = MessageDataManagerPage;
            foreach (Student student in students)
            {
                Console.WriteLine("{0}:{1}", student.Id, student.StudentName);
            }
            int studentID = 0;
            PrintAndReadInt("请输入学生编号：", students.Count, out studentID);

            foreach (Subject subject in subjects)
            {
                Console.WriteLine("{0}:{1}", subject.Id, subject.SubjectName);
            }
            int subjectID = 0;
            PrintAndReadInt("请输入科目编号：", subjects.Count, out subjectID);

            Console.Clear();

            StringBuilder s = new StringBuilder();
            s.AppendFormat("学生姓名：{0}科目名字：{1},科目成绩：{2}", students[studentID].StudentName, students[studentID].Subjects[subjectID].SubjectName, students[studentID].Subjects[subjectID].Score);
            PrintBetweenEmptyLine(s.ToString());

            LastPage();
        }

        /// <summary>
        /// 1.基本信息查询：可按年级、系别、专业对学生基本信息进行查询
        /// 2.基本信息修改：通过基本信息的查询，可对相应的信息进行修改
        /// </summary>
        private void BasicMessageManagerPage()
        {
            LastPage = PageTwo;
            PrintModule("欢迎进入基本信息管理模块", "1.基本信息查询");
            string s = Console.ReadLine();
            switch (s)
            {
                case "1":
                    Console.Clear();
                    SelectStudentBasicMessage();
                    break;
                case "2":
                    Console.Clear();
                    LastPage();
                    break;
                case "3":
                    Environment.Exit(0);
                    break;
                default:
                    Console.Clear();
                    PrintBetweenEmptyLine("输入有误，请重新输入");
                    BasicMessageManagerPage();
                    break;
            }
        }

        /// <summary>
        /// 学生基本信息查询
        /// </summary>
        private void SelectStudentBasicMessage()
        {
            LastPage = BasicMessageManagerPage;

            foreach (Profession progession in professions)
            {
                Console.WriteLine("{0}:{1}", progession.Id, progession.ProfessionName);
            }

            int professionID = 0;
            PrintAndReadInt("请输入专业编号：", professions.Count, out professionID);

            foreach (Grade grade in professions[professionID].Grades)
            {
                Console.WriteLine("{0}:{1}", grade.Id, grade.Gradename);
            }

            int gradeID = 0;
            PrintAndReadInt("请输入年级编号：", professions[professionID].Grades.Count, out gradeID);

            List<Student> students = professions[professionID].Grades[gradeID].Students;
            string[] ss = new string[students.Count];

            for (int i = 0; i < students.Count;i++ )
            {
                ss[i] = string.Format("学生ID:{0}学生姓名:{1}学生年龄:{2}",students[i].Id,students[i].StudentName,students[i].Age);
            }

            PrintModuleWithOutWrite("如需修改则输入学生ID", ss);
            int ii = -1;
            PrintAndReadInt("请输入操作编号：", ss.Length + 3, out ii);
            if (ii < ss.Length)
            {
                UpdateStudentBasicMessage(ii);
            }
            else if (ii == ss.Length + 1)
            {
                Console.Clear();
                LastPage();
            }
            else if (ii == ss.Length + 2)
            {
                Environment.Exit(0);
            }
        }

        /// <summary>
        /// 更新学生基本信息
        /// </summary>
        /// <param name="ii">学生ID</param>
        private void UpdateStudentBasicMessage(int ii)
        {
            Console.Write("请输入学生名字：");
            string studentname = Console.ReadLine();
            int age = 0;
            PrintAndReadInt("请输入学生年龄：", 0, out age);

            students[ii].StudentName = studentname;
            students[ii].Age = age;

            Console.Clear();

            PrintBeforeEmptyLine("保存成功");

            LastPage();
        }

        /// <summary>
        /// 1.对每系或每班各科成绩进行分析（即求单科平均成绩、及格率和优秀率）
        /// 2.对所开课程的成绩分析（求平均成绩，最高分，最低分）
        /// 
        /// 3.对学生考试成绩进行排名（单科按系别或班级进行排名，对每一个班级，同一学期学生总体成绩进行排名，并显示各科成绩信息）
        /// </summary>
        private void ScoreManagerPage()
        {
            LastPage = PageTwo;
            PrintModule("欢迎进入成绩管理模块", "1.成绩分析","2.对学生考试成绩进行排名");
            string s = Console.ReadLine();
            switch (s)
            {
                case "1":
                    Console.Clear();
                    ScoreAnalyse();
                    break;
                case "2":
                    Console.Clear();
                    OderByStudentScore();
                    break;
                case "3":
                    Console.Clear();
                    LastPage();
                    break;
                case "4":
                    Environment.Exit(0);
                    break;
                default:
                    Console.Clear();
                    PrintBetweenEmptyLine("输入有误，请重新输入");
                    ScoreManagerPage();
                    break;
            }
        }

        /// <summary>
        /// 成绩分析
        /// </summary>
        private void ScoreAnalyse()
        {
            LastPage = ScoreManagerPage;

            foreach (Profession progession in professions)
            {
                Console.WriteLine("{0}:{1}", progession.Id, progession.ProfessionName);
            }

            int professionID = 0;
            PrintAndReadInt("请输入专业编号：", professions.Count, out professionID);

            foreach (Grade grade in professions[professionID].Grades)
            {
                Console.WriteLine("{0}:{1}", grade.Id, grade.Gradename);
            }

            int gradeID = 0;
            PrintAndReadInt("请输入年级编号：", professions[professionID].Grades.Count, out gradeID);

            foreach (Subject subject in professions[professionID].Grades[gradeID].Subjects)
            {
                Console.WriteLine("{0}:{1}", subject.Id, subject.SubjectName);
            }

            int subjectID = 0;
            PrintAndReadInt("请输入科目编号：", professions[professionID].Grades[gradeID].Subjects.Count, out subjectID);

            Subject subject1 = professions[professionID].Grades[gradeID].Subjects[subjectID];
            string message = string.Empty;
            while (true)
            {
                PrintModuleWithOutExitWithOutTitle("1.求平均分", "2.求及格率", "3.求优秀率", "4.最高分", "5.最低分");
                string choice = Console.ReadLine();
                if (choice.Equals("1"))
                {
                    message = string.Format("科目:{0}平均分:{1}",subject1.SubjectName,subject1.AvgScore());
                    break;
                }
                else if (choice.Equals("2"))
                {
                    message = string.Format("科目:{0}及格率:{1}", subject1.SubjectName, subject1.PassOdds());
                    break;
                }
                else if (choice.Equals("3"))
                {
                    message = string.Format("科目:{0}优秀率:{1}", subject1.SubjectName, subject1.GoodOdds());
                    break;
                }
                else if (choice.Equals("4"))
                {
                    message = string.Format("科目:{0}最高分:{1}", subject1.SubjectName, subject1.MaxScore());
                    break;
                }
                else if (choice.Equals("5"))
                {
                    message = string.Format("科目:{0}最低分:{1}", subject1.SubjectName, subject1.MinScore());
                    break;
                }
                else
                {
                    PrintBetweenEmptyLine("输入有误请重新输入");
                }
            }

            Console.Clear();

            Console.WriteLine(message);

            LastPage();
        }

        /// <summary>
        /// 学生考试成绩进行排名
        /// </summary>
        private void OderByStudentScore()
        {
            LastPage = ScoreManagerPage;

            foreach (Profession progession in professions)
            {
                Console.WriteLine("{0}:{1}", progession.Id, progession.ProfessionName);
            }

            int professionID = 0;
            PrintAndReadInt("请输入专业编号：", professions.Count, out professionID);

            foreach (Grade grade in professions[professionID].Grades)
            {
                Console.WriteLine("{0}:{1}", grade.Id, grade.Gradename);
            }

            int gradeID = 0;
            PrintAndReadInt("请输入年级编号：", professions[professionID].Grades.Count, out gradeID);

            foreach (Subject subject in professions[professionID].Grades[gradeID].Subjects)
            {
                Console.WriteLine("{0}:{1}", subject.Id, subject.SubjectName);
            }

            string message = string.Format("专业：{0}年级：{1}排行榜", professions[professionID].ProfessionName, professions[professionID].Grades[gradeID].Gradename);

            PrintBetweenEmptyLine(message);

            List<Student> stus = professions[professionID].Grades[gradeID].OrderByStudentScore();

            Console.Clear();

            foreach (Student stu in stus)
            {
                Console.WriteLine("学生姓名{0}总成绩{1}",stu.StudentName,stu.SumScore());
                foreach (Subject sub in stu.Subjects)
                {
                    Console.Write("科目{0}成绩{1}",sub.SubjectName,sub.Score);
                }
                Console.WriteLine();
            }

            LastPage();
        }

        private void PrintAndReadInt(string message,int listCount, out int t)
        {
            bool flag = true;
            do
            {
                Console.Write(message);
                string s = Console.ReadLine();
                flag = int.TryParse(s, out t);
                if (!flag || t >= listCount)
                {
                    Console.WriteLine("您输入有误，请重新输入");
                }
            } while (flag == false || t >= listCount);
        }

        private void PrintModuleWithOutTitle(params string[] models)
        {
            foreach (string s in models)
            {
                PrintBeforeEmptyLine(s);
            }
            PrintBeforeEmptyLine(models.Length + 1 + ":返回上一级菜单");
            PrintBeforeEmptyLine(models.Length + 2 + ":退出系统");
            PrintStar(15);
            Console.WriteLine();
            Console.Write("请输入操作编号:");
        }

        private void PrintModule(string title, params string[] models)
        {
            PrintMenu(title);
            foreach (string s in models)
            {
                PrintBeforeEmptyLine(s);
            }
            PrintBeforeEmptyLine(models.Length+1+":返回上一级菜单");
            PrintBeforeEmptyLine(models.Length+2+":退出系统");
            PrintStar(15);
            Console.WriteLine();
            Console.Write("请输入操作编号:");
        }

        private void PrintModuleWithOutWrite(string title, params string[] models)
        {
            PrintMenu(title);
            foreach (string s in models)
            {
                PrintBeforeEmptyLine(s);
            }
            PrintBeforeEmptyLine(models.Length+1+":返回上一级菜单");
            PrintBeforeEmptyLine(models.Length+2+":退出系统");
            PrintStar(15);
            Console.WriteLine();
        }

        private void PrintModuleWithOutExitWithOutTitle(params string[] models)
        {
            foreach (string s in models)
            {
                PrintBeforeEmptyLine(s);
            }
            PrintStar(15);
            Console.WriteLine();
            Console.Write("请输入操作编号:");
        }

        private void PrintModuleWithOutExit(string title, params string[] models)
        {
            PrintMenu(title);
            foreach (string s in models)
            {
                PrintBeforeEmptyLine(s);
            }
            PrintStar(15);
            Console.WriteLine();
            Console.Write("请输入操作编号:");
        }

        private void PrintBeforeEmptyLine(string message)
        {
            Console.WriteLine();
            Console.WriteLine(message);
        }

        private void PrintAfterEmptyLine(string message)
        {
            Console.WriteLine(message);
            Console.WriteLine();
        }

        private void PrintBetweenEmptyLine(string message)
        {
            Console.WriteLine();
            Console.WriteLine(message);
            Console.WriteLine();
        }

        private void PrintMenu(string message)
        {
            PrintStar(5);
            Console.Write(message);
            PrintStar(5);
            Console.WriteLine();
        }

        private void init()
        {
            subjects.Add(new Subject(0, "语文",0,new List<Student>()));
            subjects.Add(new Subject(1, "数学", 0, new List<Student>()));
            subjects.Add(new Subject(2, "英语", 0, new List<Student>()));

            List<Grade> grades = new List<Grade>();
            for (int i = 0; i < 5; i++)
            {
                grades.Add(new Grade(i, i + 1 + "级", new List<Student>(),new List<Subject>(subjects)));
            }
            professions.Add(new Profession(0, "建筑", new List<Grade>(grades)));
            professions.Add(new Profession(1, "IT", new List<Grade>(grades)));
            professions.Add(new Profession(2, "通讯", new List<Grade>(grades)));
        }

        private void PrintStar(int count)
        {
            for (int i = 0; i < count; i++)
                Console.Write("*");
        }

        private List<Profession> professions = new List<Profession>();

        private List<Subject> subjects = new List<Subject>();

        private List<Student> students = new List<Student>();

        private event Action LastPage;
    }
}
